#include "TraceResult.h"
#include <assert.h>

TraceResult::TraceResult()
{
	Reset();
}

TraceResult::~TraceResult()
{
	Reset();
}

void TraceResult::Reset()
{
	mHits.clear();
	mNumberOfRayTriangleTesting = 0;
	mNumberOfRayAABBTesting = 0;
	mbCanStopTrace = false;
}

bool TraceResult::HitAny() const
{
	return mHits.size() > 0;
}

size_t TraceResult::NumberOfHits() const
{
	return mHits.size();
}

const TSceneIntersection* TraceResult::GetHit(size_t index) const
{
	if (0 <= index && index < mHits.size())
	{
		return &mHits[index];
	}
	else
	{
		assert(0);
		return NULL;
	}
}

size_t TraceResult::NumberOfRayAABBTesting() const
{
	return mNumberOfRayAABBTesting;
}

size_t TraceResult::NumberOfRayTriangleTesting() const
{
	return mNumberOfRayTriangleTesting;
}

void TraceResult::AddHit(const TSceneIntersection& hit, TraceType traceType)
{
	if (!mbCanStopTrace)
	{
		if (kStopOnFirstHit == traceType)
		{
			assert(mHits.size() == 0);
			mHits.push_back(hit);
			mbCanStopTrace = true;
		}
		else if (kNearestHit == traceType)
		{
			assert(mHits.size() <= 1);
			if (mHits.size() == 1)
			{
				if (mHits[0].dist > hit.dist)
				{
					mHits[0] = hit;
				}
			}
			else
			{
				mHits.push_back(hit);
			}
		}
		else // kAllHits
		{
			mHits.push_back(hit);	
		}
	}
}

bool TraceResult::CanStopTrace() const
{
	return mbCanStopTrace;
}

void TraceResult::AddRayTriangleTesting()
{
	mNumberOfRayTriangleTesting++;
}

void TraceResult::AddRayAABBTesting()
{
	mNumberOfRayAABBTesting++;
}
